package com.ruoyi.trade.service.impl;


import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.CoinConstant;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.HttpUtil;
import com.ruoyi.trade.domain.TPairs;
import com.ruoyi.trade.mapper.TPairsMapper;
import com.ruoyi.trade.service.KlineJobService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.*;

@Service
@Slf4j
public class KlineServiceImpl implements KlineJobService {
	@Resource
	private TPairsMapper pairsMapper;

	@Autowired
	private RedisCache redisCache;

	private final static int orderCount = 12;

	@Override
	public void SynchKline(String timeType) {
		QueryWrapper<TPairs> wrapper = new QueryWrapper<TPairs>();
		wrapper.eq("state", CoinConstant.Coin_State.NORMAL);
		List<TPairs> list = pairsMapper.selectList(wrapper);
		ThreadPoolExecutor es = new ThreadPoolExecutor(10, 30, 2L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(),
				new ThreadFactory() {
					@Override
					public Thread newThread(Runnable r) {
						Thread t = new Thread(r);
						t.setDaemon(true);
						return t;
					}
				});
		List<TPairs> listOneThrade = list.subList(0, 10);
		for (TPairs pairs : listOneThrade) {
			es.submit(new getInitKline(pairs, timeType));
		}
		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		List<TPairs> listTwoThrade = list.subList(10, list.size());
		for (TPairs pairs : listTwoThrade) {
			es.submit(new getInitKline(pairs, timeType));
		}
		es.shutdown();

	}



	class getInitKline implements Runnable {

		private TPairs pairs;

		private String timeType;

		getInitKline(TPairs pairs, String timeType) {
			this.pairs = pairs;
			this.timeType = timeType;
		}

		@Override
		public void run() {
			try {
				String pairsName = pairs.getPairsName();
				String type = pairs.getType();
				String redisKey = CacheConstants.KLINE_KEY + type + CacheConstants.SPLIT+ timeType + CacheConstants.SPLIT + pairs.getPairsName();
				String contentBn;
				if(type.equals(CoinConstant.Coin_Type.CONTRACT)){//合约
					contentBn =  HttpUtil.doGet("https://api.binance.com/fapi/v1/klines?symbol="
							+ pairsName.replace("/", "").toUpperCase() + "&interval=" + timeType + "&limit=1");
				}else{
					contentBn =  HttpUtil.doGet("https://api.binance.com/api/v3/klines?symbol="
							+ pairsName.replace("/", "").toUpperCase() + "&interval=" + timeType + "&limit=1");
				}
				JSONArray jsonArray = JSONArray.parseArray(contentBn);
				String sss = jsonArray.get(0).toString();
				JSONArray jsonInfo = JSONArray.parseArray(sss);
				Long time = jsonInfo.getLong(0);
				BigDecimal open = jsonInfo.getBigDecimal(1);
				BigDecimal high = jsonInfo.getBigDecimal(2);
				BigDecimal low = jsonInfo.getBigDecimal(3);
				BigDecimal close = jsonInfo.getBigDecimal(4);
				BigDecimal amount = jsonInfo.getBigDecimal(5);
				BigDecimal volume = jsonInfo.getBigDecimal(5);
				BigDecimal vol = jsonInfo.getBigDecimal(7);
				BigDecimal count = jsonInfo.getBigDecimal(8);

				JSONObject jsonInfoResult = new JSONObject();
				String timeStr = String.valueOf(time);
				jsonInfoResult.put("volume", volume);
				jsonInfoResult.put("high", high);
				jsonInfoResult.put("amount", amount);
				jsonInfoResult.put("vol", vol);
				jsonInfoResult.put("low", low);
				jsonInfoResult.put("count", count);
				jsonInfoResult.put("time", time);
				jsonInfoResult.put("close", close);
				jsonInfoResult.put("open", open);
				jsonInfoResult.put("id", timeStr.substring(0, timeStr.length() - 3));
				//计算涨跌额 = 收盘-开盘
				jsonInfoResult.put("change", close.subtract(open));
				//计算涨跌幅 = （收盘-开盘）/开盘*100%
				jsonInfoResult.put("changePercent", close.subtract(open).divide(open, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")));
				redisCache.zsetRmByScore(redisKey, time);
				redisCache.zsetAdd(redisKey, jsonInfoResult.toJSONString(), time);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}
}
